module ysyx_050369_dcache (
    input           clk,
    input           rst,
    input           flush,
    input           i_stop,
    input           i_wb_fence,
    input           i_mem_wen,
    input [31:0]    i_mem_waddr,
    input [63:0]    i_mem_wdata,
    input [7 :0]    i_mem_wmask,
    input           i_mem_ren,
    input [31:0]    i_mem_raddr,
    input [7 :0]    i_mem_rmask,
    output [63:0]   o_mem_rdata,
    output reg      o_fdone,
//////////////////////////////////////////
    input  [31:0]   i_pc,
    input  [31:0]   i_inst,
    input           i_reg_wen,
    input [4 :0]    i_reg_waddr,
    input [63:0]    i_reg_res,
    input           i_ctreg_valid,
    input [63:0]    i_ctreg_data,
    output reg[31:0]o_inst, 
    output    [63:0]o_reg_wdata, 
    output reg      o_reg_wen, 
    output reg[4:0] o_reg_waddr,
    output reg      o_mem_ren,
    output reg[31:0]o_mem_raddr,
    output reg      o_dev,
    output   [127:0]o_cache_data,
`ifdef ysyx_050369_SOC
    output [5:0]    io_sram0_addr,
	output          io_sram0_cen,
	output          io_sram0_wen,
	output [127:0]  io_sram0_wmask,
	output [127:0]  io_sram0_wdata,
	input [127:0]   io_sram0_rdata,
	output [5:0]    io_sram1_addr,
	output          io_sram1_cen,
	output          io_sram1_wen,
	output [127:0]  io_sram1_wmask,
	output [127:0]  io_sram1_wdata,
	input [127:0]   io_sram1_rdata,
    output [5:0]    io_sram2_addr,
	output          io_sram2_cen,
	output          io_sram2_wen,
	output [127:0]  io_sram2_wmask,
	output [127:0]  io_sram2_wdata,
	input [127:0]   io_sram2_rdata,
    output [5:0]    io_sram3_addr,
	output          io_sram3_cen,
	output          io_sram3_wen,
	output [127:0]  io_sram3_wmask,
	output [127:0]  io_sram3_wdata,
	input [127:0]   io_sram3_rdata,
`else
    output reg[31:0]o_pc, 
`endif 
	output     [2:0]size_t,
    output          axi_read ,
    output          unbrust,
    output          uncache,
    output  [31:0]  i_raddr,
    output  [31:0]  i_waddr,
    output  [7 :0]  wstrb_t,
    output 			axi_write,
    output    [31:0]dirty_addr,
    output 	[127:0] i_wdata,

    input   [127:0] i_axi_data,
    input           i_axi_wen ,
    input           wdone,
    input           rdone,
    output          axi_stop
);

`ifndef ysyx_050369_SOC
    wire  [5:0]    io_sram0_addr;
	wire           io_sram0_cen;
	wire           io_sram0_wen;
	wire  [127:0]  io_sram0_wmask;
	wire  [127:0]  io_sram0_wdata;
	wire [127:0]   io_sram0_rdata;
	wire  [5:0]    io_sram1_addr;
	wire           io_sram1_cen;
	wire           io_sram1_wen;
	wire  [127:0]  io_sram1_wmask;
	wire  [127:0]  io_sram1_wdata;
	wire [127:0]   io_sram1_rdata;
    wire  [5:0]    io_sram2_addr;
	wire           io_sram2_cen;
	wire           io_sram2_wen;
	wire  [127:0]  io_sram2_wmask;
	wire  [127:0]  io_sram2_wdata;
	wire [127:0]   io_sram2_rdata;
    wire  [5:0]    io_sram3_addr;
	wire           io_sram3_cen;
	wire           io_sram3_wen;
	wire  [127:0]  io_sram3_wmask;
	wire  [127:0]  io_sram3_wdata;
	wire [127:0]   io_sram3_rdata;
    reg          mem_wen;
    reg[31:0]    mem_waddr;
`else
    reg [31:0] o_pc;
`endif 
reg [31:0]   pc,inst;
reg          reg_wen;
reg [4 :0]   reg_waddr;
reg [63:0]   reg_res;
reg          mem_ren;
reg[31:0]    mem_raddr;
reg[7 :0]    mem_rmask;
reg          ctreg_valid;
reg[63:0]    ctreg_data;
reg          de_ctreg_valid;
reg [63:0]   de_ctreg_data;
reg [63:0]   reg_wdata;
//cache informtion
wire [3:0]   offset;
wire [5:0]   idx;
wire [21:0]  tag;
wire 		 channl0_hit;
wire 		 channl1_hit;
wire 		 channl2_hit;
wire 		 channl3_hit;
wire 		 data_hit;
wire [3:0]   hit;

reg [127:0] wdata ;
wire [7:0]   mask;
wire 		 data_dirty;
wire 		 dev;
wire [3:0]   wen;
wire        mem_en;

// wire         i_axi_wen;
// wire [127:0] i_axi_data;
wire [127:0] cache_wmask;
wire [127:0] cache_wdata;
reg  [31:0]  i_de_pc;
wire         i_pc_update;
reg  [31:0]  dev_done_pc;
wire         dev_done;
wire [3:0]   cache_wen ;
always @(posedge clk ) begin
    if (rst) begin
        i_de_pc <= 'b0;
        dev_done_pc <= 'b0;
    end
    else begin
        i_de_pc <= i_pc;
        if (i_pc_update) begin
            dev_done_pc <= 'b0;
        end
        else if (uncache&&(i_mem_ren&&rdone)||(i_mem_wen&&wdone)) begin
            dev_done_pc <= i_pc;
        end
    end
end
assign i_pc_update = i_pc != i_de_pc;
assign dev_done = dev_done_pc == i_pc;
assign mem_en =   i_mem_ren||i_mem_wen;
////////////////////////////////
//cache中的信息包含
///////////////////////////////
reg [21:0] channl_tag [63:0][3:0];
reg [3:0]  valid [63:0];
reg [3:0]  dirty [63:0] ;
reg [1:0]  count [63:0];
integer  i;
always @(posedge clk ) begin
	if (rst) begin
		for (i =0 ; i<64 ; i++) begin
			channl_tag[0][i] <= 22'b0;
			channl_tag[1][i] <= 22'b0;
			channl_tag[2][i] <= 22'b0;
			channl_tag[3][i] <= 22'b0;
			valid        [i] <= 4'b0;
			count        [i] <= 2'b0;
            dirty[i]       <= 4'b0;
		end
	end
	else begin
		if (i_axi_wen&&~uncache) begin
			channl_tag[idx][count[idx]] <= tag;
			valid [idx][count[idx]]     <= 1'b1;
            dirty [idx][count[idx]]     <= 1'b0;
			count [idx]					<= count[idx] + 1;
            
		end
        if (~dev&&i_mem_wen&&~i_stop) begin
            dirty[idx]<=dirty[idx] | hit;
        end
	end
end

///////////////////////////////
//////////////////////////////
///////////////////////////////
//第一周期负责解析出各种信息
///////////////////////////////
assign offset      = i_mem_raddr[3:0];
assign idx         = i_mem_raddr[9:4];
assign tag         = i_mem_raddr[31:10];
assign mask        = i_mem_wen?i_mem_wmask:i_mem_rmask;
assign hit		   = {channl3_hit,channl2_hit,channl1_hit,channl0_hit};
assign channl0_hit = channl_tag[idx][0]==tag && valid[idx][0];
assign channl1_hit = channl_tag[idx][1]==tag && valid[idx][1];
assign channl2_hit = channl_tag[idx][2]==tag && valid[idx][2];
assign channl3_hit = channl_tag[idx][3]==tag && valid[idx][3];
assign data_hit    = channl0_hit||channl1_hit||channl2_hit||channl3_hit;

// assign unbrust     = 1'b1;
assign wen[0]	   = (i_axi_wen&&(~count[idx][1] && ~count[idx][0]))?1'b0:1'b1;
assign wen[1]	   = (i_axi_wen&&(~count[idx][1] &&  count[idx][0]))?1'b0:1'b1;
assign wen[2]	   = (i_axi_wen&&( count[idx][1] && ~count[idx][0]))?1'b0:1'b1;
assign wen[3]	   = (i_axi_wen&&( count[idx][1] &&  count[idx][0]))?1'b0:1'b1;
assign data_dirty  = dirty[idx][count[idx]];
assign cache_wen   = (~dev&&i_mem_wen)?(~hit):4'hf;
assign cache_wdata = {64'b0,i_mem_wdata}<<{offset,3'b0};
assign cache_wmask = ({64'b0,cache_wmask_t}<<{offset,3'b0}) ^ 128'hffff_ffff_ffff_ffff_ffff_ffff_ffff_ffff;
// assign axi_stop    = ((mem_en)&&((~uncache&&~data_hit)||(uncache&&((~rdone&&axi_read)||(~wdone&&axi_write)))));

assign axi_stop    = (mem_en&&((~uncache&&~data_hit)||(uncache&&(~dev_done && mem_en))));
`ifdef ysyx_050369_SOC
assign dev         = (mem_en&&(tag[21]==1'h1 || tag[21:18]==4'h3))?1'b0:1'b1;
assign unbrust     = ~tag[21] ;
`else
assign dev         = (mem_en&&(tag[21:18]!=4'h8))?1'b1:1'b0;
assign unbrust     = tag[21:18]!=4'h8;
`endif
wire [63:0] slv_wdate;
reg [63:0] cache_wmask_t;
// always @(*) begin
//     case (count[idx])
//     `ifdef ysyx_050369_SOC
//         2'b00 : dirty_addr = fence_en?{channl_tag[idx_cnt][chnl_cnt],idx_cnt,4'b0}:{channl_tag[idx][0],idx,4'b0};
//         2'b01 : dirty_addr = fence_en?{channl_tag[idx_cnt][chnl_cnt],idx_cnt,4'b0}:{channl_tag[idx][1],idx,4'b0};
//         2'b10 : dirty_addr = fence_en?{channl_tag[idx_cnt][chnl_cnt],idx_cnt,4'b0}:{channl_tag[idx][2],idx,4'b0};
//         2'b11 : dirty_addr = fence_en?{channl_tag[idx_cnt][chnl_cnt],idx_cnt,4'b0}:{channl_tag[idx][3],idx,4'b0}; 
//         default: dirty_addr = 'b0;
//     `else
//         2'b00 : dirty_addr = {channl_tag[idx][0],idx,4'b0};
//         2'b01 : dirty_addr = {channl_tag[idx][1],idx,4'b0};
//         2'b10 : dirty_addr = {channl_tag[idx][2],idx,4'b0};
//         2'b11 : dirty_addr = {channl_tag[idx][3],idx,4'b0}; 
//         default: dirty_addr = 'b0;
//     `endif 
//     endcase
// end
assign dirty_addr = {channl_tag[idx][count[idx]],idx,4'b0};
assign wstrb_t[7:4] = mask[3]?4'hf:'b0;
assign wstrb_t[3:2] = mask[2]?2'h3:'b0;
assign wstrb_t[ 1 ] = mask[1]?1'h1:'b0;
assign wstrb_t[ 0 ] = mask[0]?1'h1:'b0;
assign cache_wmask_t[63:32] = mask[3]?32'hffffffff:'b0;
assign cache_wmask_t[31:16] = mask[2]?16'hffff:'b0;
assign cache_wmask_t[15:8 ] = mask[1]?8'hff:'b0;
assign cache_wmask_t[7 :0 ] = mask[0]?8'hff:'b0;
assign size_t = mask[3] ? 3'h3:
                mask[2] ? 3'h2:
                mask[1] ? 3'h1: 3'h0;

///////////////////////////////
////第二周期判断是否为cache数据，发送读写命令，
///////////////////////////////
reg  [3:0]      de_hit;
reg [63:0]      de_mem_rdata;
wire [127+64:0]    mem_rdata_cache;
reg [127:0]     mem_rdata_cache_r;
wire [63:0]    mem_rdata_temp;
reg             de_stop;
reg [63:0]      mem_rdata;
wire            o_pc_update ;
reg   [31:0]    de_pc;
reg   [63:0]    mem_data_buffer;
reg   [63:0]    dev_data;
reg   [8:0]     mem_addr_high;
always @(posedge clk ) begin
	if(rst)begin
		de_stop <= 'b0;
	end
	else begin
		de_stop <= i_stop;
	end
end

always @(posedge clk ) begin
    if (rst||flush) begin
        o_dev          <= 'b0;
        de_hit          <= 'b0;
        reg_wdata       <= 'b0;
        o_reg_wen       <= 'b0;
        o_reg_waddr     <= 'b0;
        o_pc            <= 'b0;
        o_inst          <= 'b0;
        o_mem_ren       <= 'b0;
        o_mem_raddr     <= 'b0;
        de_pc           <= 'b0;
        mem_data_buffer <= 'b0;
        de_ctreg_valid  <= 'b0;
        de_ctreg_data   <= 'b0;
        mem_rmask       <= 'b0;
        dev_data        <= 'b0;
        mem_addr_high   <= 'b0;
    end
    else begin
        if (~i_stop) begin
            de_hit          <= hit;
            o_dev           <= dev;
            reg_wdata       <= i_reg_res ;
            o_reg_wen       <= i_reg_wen;
            o_reg_waddr     <= i_reg_waddr;
            o_pc            <= i_pc;
            o_inst          <= i_inst;
            o_mem_raddr     <= i_mem_raddr;
            o_mem_ren       <= i_mem_ren;
            de_ctreg_valid  <= i_ctreg_valid;
            de_ctreg_data   <= i_ctreg_data;
            mem_rmask       <= i_mem_rmask;
            dev_data        <= i_axi_data[63:0];
        end
        de_pc <= o_pc;
        if (~de_stop) begin
            de_mem_rdata<= o_dev?i_axi_data[63:0]:mem_rdata;
            mem_rdata_cache_r <= mem_rdata_cache[127:0];
            mem_addr_high   <= {2'b0,o_mem_raddr[3:0],3'b0}+63;
        end
    end
end

assign mem_rdata_cache[127:0]= de_hit[0]? io_sram0_rdata :
                        de_hit[1]? io_sram1_rdata :
                        de_hit[2]? io_sram2_rdata :
                        de_hit[3]? io_sram3_rdata : 'b0;
assign mem_rdata_cache[127+64:128] = 0;

assign  mem_rdata_temp  = mem_rdata_cache[({1'b0,o_mem_raddr[3:0],3'b0})+:64];

assign o_cache_data   = o_pc_update    ?mem_rdata_cache[127:0]:mem_rdata_cache_r;
always @(*) begin
    case (mem_rmask)
        8'h01 : mem_rdata = {{56{mem_rdata_temp[ 7]}},mem_rdata_temp[ 7:0]};
        8'h03 : mem_rdata = {{48{mem_rdata_temp[15]}},mem_rdata_temp[15:0]};
        8'h07 : mem_rdata = {{32{mem_rdata_temp[31]}},mem_rdata_temp[31:0]};
        8'h0f : mem_rdata =                           mem_rdata_temp[63:0] ;
        8'h81 : mem_rdata = {56'b0                   ,mem_rdata_temp[ 7:0]};
        8'h83 : mem_rdata = {48'b0                   ,mem_rdata_temp[15:0]};
        8'h87 : mem_rdata = {32'b0                   ,mem_rdata_temp[31:0]};
        default: mem_rdata = 'b0;
    endcase
end
assign o_pc_update      = (o_pc!= de_pc);
assign o_mem_rdata      =   de_ctreg_valid  ?de_ctreg_data  :
                            (o_dev          ?dev_data       : 
                            (o_pc_update    ?mem_rdata:de_mem_rdata));
assign o_reg_wdata      = o_mem_ren ?o_mem_rdata : reg_wdata ;

//////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////fence_i 指令部分
//////////////////////////////////////////////////////////////////////////////////////////////
wire fence_en;
reg [3:0]   fstate,fnstate;
reg [5:0]   idx_cnt;
reg [1:0]   chnl_cnt;
reg [127:0] fdata;
reg         fwen;
`ifdef ysyx_050369_SOC
parameter FIDLE=0 ,CHNL0 = 1,CHNL1=2,CHNL2=3,CHNL3=4,READ_CACHE=5,WRITE=6,FIN=7,FDONE=8;
assign slv_wdate =  mask[3]?i_mem_wdata:
                    mask[2]?{2{i_mem_wdata[31:0]}}:
                    mask[1]?{4{i_mem_wdata[15:0]}}:
                    mask[0]?{8{i_mem_wdata[7:0]}}:'b0;

assign fence_en = fnstate > FIDLE;
always @(posedge clk) begin
    if (rst) fstate <= FIDLE;
    else     fstate <= fnstate;
end
always @(*) begin
    case (fstate)
        FIDLE: fnstate = i_wb_fence?CHNL0:FIDLE;
        CHNL0,CHNL1,CHNL2,CHNL3:begin
            if (dirty[idx_cnt][chnl_cnt]) begin
                fnstate = READ_CACHE;
            end
            else if (chnl_cnt==2'b11 && idx_cnt==6'd63) begin
                fnstate = FDONE;
            end
            else begin
                case (chnl_cnt)
                    2'b00:fnstate = CHNL0;
                    2'b01:fnstate = CHNL1;
                    2'b10:fnstate = CHNL2;
                    2'b11:fnstate = CHNL3;
                endcase
            end
        end  
        READ_CACHE: fnstate = WRITE;
        WRITE:      fnstate = wdone?FIN:WRITE;
        FIN:begin 
            if (chnl_cnt==2'b11 && idx_cnt==6'd63) begin
                fnstate = FDONE;
            end
            else begin
                case (chnl_cnt)
                    2'b00:fnstate = CHNL0;
                    2'b01:fnstate = CHNL1;
                    2'b10:fnstate = CHNL2;
                    2'b11:fnstate = CHNL3;
                endcase
            end
            
        end
        FDONE:fnstate = FIDLE;
        default: fnstate = FIDLE;
    endcase
end
always @(posedge clk ) begin 
	if(rst) begin
		idx_cnt <= 'b0;
        fdata   <= 'b0;
        fwen    <= 'b0;
        chnl_cnt<= 'b0;
        o_fdone <= 'b0;
	end 
    else begin
		case (fnstate)
			FIDLE:begin
                idx_cnt <= 'b0;
                fdata   <= 'b0;
                fwen    <= 'b0;
                chnl_cnt<= 'b0;
                o_fdone <= 'b0;
            end
			CHNL0,CHNL1,CHNL2,CHNL3:begin 
                if (idx_cnt == 6'd63 && chnl_cnt != 2'b11) begin
                    chnl_cnt <= chnl_cnt + 1;
                    idx_cnt  <= 6'h0;
                end
				else if (~dirty[idx_cnt][chnl_cnt]) begin
					idx_cnt <= idx_cnt + 1;
				end
			end
			READ_CACHE:begin 
				
			end
			WRITE:begin 
				fwen <= 1'b1;
                case (chnl_cnt)
                    2'b00:fdata <= io_sram0_rdata;
                    2'b01:fdata <= io_sram1_rdata;
                    2'b10:fdata <= io_sram2_rdata;
                    2'b11:fdata <= io_sram3_rdata;
                endcase
			end
			FIN:begin 
                fwen <= 1'b0;
                if (idx_cnt == 6'd63 && chnl_cnt != 2'b11) begin
                    chnl_cnt <= chnl_cnt + 1;
                    idx_cnt  <= 6'h0;
                end
                else if(idx_cnt != 6'd63 || chnl_cnt != 2'b11) begin
                    idx_cnt <= idx_cnt + 1; 
                end
			end
            FDONE: begin
                o_fdone <= 1'b1;
            end
			default : begin end/* default */
		endcase
	end
end
`else
    assign fence_en = 1'b0;
    assign slv_wdate     = i_mem_wdata;
`endif 




`ifdef ysyx_050369_SOC
assign uncache  = ~fence_en&&tag[21]!=1'b1&&tag[21:18]!=4'h3;
assign i_wdata  =  fence_en?fdata:(uncache?{64'b0,slv_wdate}:wdata);
assign axi_read =  fence_en?1'b0:( ~i_ctreg_valid&&((~uncache && (~data_hit) && mem_en) 
                                                  ||( uncache && i_mem_ren   &&i_pc_update)));
                
assign axi_write=  fence_en?fwen :(~i_ctreg_valid&&((~uncache  && data_dirty && (~data_hit)&& mem_en)
                                                   ||(uncache  && i_mem_wen  && i_pc_update)));
assign i_raddr  = uncache?{tag,idx,offset}:{tag,idx,4'b0};
assign i_waddr  = fence_en?{channl_tag[idx_cnt][chnl_cnt],idx_cnt,4'b0}:(uncache?{tag,idx,offset}:data_dirty?dirty_addr:{tag,idx,4'b0});

`else


assign uncache  = tag[21:18]!=4'h8 ;
assign i_wdata  =  uncache?{64'b0,slv_wdate}:wdata;
assign axi_read =  ~i_ctreg_valid  &&((~uncache && (~data_hit) && mem_en) 
                                    ||( uncache && i_mem_ren   && ~rdone && ~dev_done));
                
assign axi_write=  ~i_ctreg_valid &&((~uncache  && data_dirty && (~data_hit)&& mem_en)
                                    ||(uncache  && i_mem_wen  && ~wdone &&  ~dev_done));
assign i_raddr  = uncache?{tag,idx,offset}:{tag,idx,4'b0};
assign i_waddr  = uncache?{tag,idx,offset}:data_dirty?dirty_addr:{tag,idx,4'b0};

`endif 
always @(*) begin
    case (count[idx])
        2'b00 : wdata = io_sram0_rdata;
        2'b01 : wdata = io_sram1_rdata;
        2'b10 : wdata = io_sram2_rdata;
        2'b11 : wdata = io_sram3_rdata;
        default: wdata = 'b0;
    endcase
end

`ifndef ysyx_050369_SOC
   S011HD1P_X32Y2D128_BW Icache0(
        .Q      (io_sram0_rdata), 
        .CLK    (clk), 
        .CEN    (io_sram0_cen), 
        .WEN    (io_sram0_wen), 
        .BWEN   (io_sram0_wmask), 
        .A      (io_sram0_addr), 
        .D      (io_sram0_wdata)
    );
   S011HD1P_X32Y2D128_BW Icache1(
        .Q      (io_sram1_rdata), 
        .CLK    (clk), 
        .CEN    (io_sram1_cen), 
        .WEN    (io_sram1_wen), 
        .BWEN   (io_sram1_wmask), 
        .A      (io_sram1_addr), 
        .D      (io_sram1_wdata)
    );
   S011HD1P_X32Y2D128_BW Icache2(
        .Q      (io_sram2_rdata), 
        .CLK    (clk), 
        .CEN    (io_sram2_cen), 
        .WEN    (io_sram2_wen), 
        .BWEN   (io_sram2_wmask), 
        .A      (io_sram2_addr), 
        .D      (io_sram2_wdata)
    );
   S011HD1P_X32Y2D128_BW Icache3(
        .Q      (io_sram3_rdata), 
        .CLK    (clk), 
        .CEN    (io_sram3_cen), 
        .WEN    (io_sram3_wen), 
        .BWEN   (io_sram3_wmask), 
        .A      (io_sram3_addr), 
        .D      (io_sram3_wdata)
    );
`endif

assign io_sram0_addr    = fence_en?idx_cnt:idx;
assign io_sram0_cen     = 'b0;
assign io_sram0_wen     = i_axi_wen?(uncache?1'b1:wen[0]):(uncache?1'b1:cache_wen[0]);
//dev?1'b1:(axi_wreq?axi_wen[0]:cache_wen[0]);
assign io_sram0_wmask   = i_axi_wen?'b0:cache_wmask;
assign io_sram0_wdata   = i_axi_wen?i_axi_data:cache_wdata;
assign io_sram1_addr    = fence_en?idx_cnt:idx;
assign io_sram1_cen     = 'b0;
assign io_sram1_wen     = i_axi_wen?(uncache?1'b1:wen[1]):(uncache?1'b1:cache_wen[1]);
assign io_sram1_wmask   = i_axi_wen?'b0:cache_wmask;
assign io_sram1_wdata   = i_axi_wen?i_axi_data:cache_wdata;
assign io_sram2_addr    = fence_en?idx_cnt:idx;
assign io_sram2_cen     = 'b0;
assign io_sram2_wen     = i_axi_wen?(uncache?1'b1:wen[2]):(uncache?1'b1:cache_wen[2]);
assign io_sram2_wmask   = i_axi_wen?'b0:cache_wmask;
assign io_sram2_wdata   = i_axi_wen?i_axi_data:cache_wdata;
assign io_sram3_addr    = fence_en?idx_cnt:idx;
assign io_sram3_cen     = 'b0;
assign io_sram3_wen     = i_axi_wen?(uncache?1'b1:wen[3]):(uncache?1'b1:cache_wen[3]);
assign io_sram3_wmask   = i_axi_wen?'b0:cache_wmask;
assign io_sram3_wdata   = i_axi_wen?i_axi_data:cache_wdata;

endmodule